home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1993 / Internet Info CD-ROM (Walnut Creek) (1993).iso / networking / news / readers / nn / nn6.4.patch12 < prev    next >
Encoding:
Text File  |  1990-11-07  |  58.0 KB  |  1,987 lines

  1.          This is an official patch to nn release 6.4
  2.          -------------------------------------------
  3.  
  4.                    PATCH #12
  5.  
  6.                 Priority: LOW
  7.  
  8.  
  9. This patch contains mainly updates to the documentation for the
  10. new features introduced in previous patches, but a number of minor bugs
  11. have been fixed and some new features related to the init files have
  12. been introduced.
  13.  
  14. As usual, all changes are described in the updated RELEASE_NOTES file
  15. (read that for more details about this patch).  Thanks to all who
  16. reported bugs and provided fixes.
  17.  
  18. To apply this patch, use nn's :patch command, or run this command from
  19. the shell in the root of the nn source tree:
  20.     patch -p0 < this-article
  21.  
  22. Then run "make all" and "./inst u".
  23.  
  24. ++Kim Storm
  25.  
  26. ===================================================================
  27.  
  28. *** ./LAST/SPLITNN1    Tue Apr 24 17:13:08 1990
  29. --- SPLITNN1    Fri Nov  2 20:54:16 1990
  30. ***************
  31. *** 1,6 ****
  32. --- 1,12 ----
  33.   # split nn.1 in 4 parts
  34.   cd man
  35.   
  36. + if [ ! -f nn.1 ] ; then
  37. +     echo "nn.1 missing: cannot split it!"
  38. +     exit 1
  39. + fi
  40. + rm -f nn.1.[ABCD]
  41.   sed -n \
  42.   -e '/BEGINPART A/,/ENDPART A/w nn.1.A' \
  43.   -e '/BEGINPART B/,/ENDPART B/w nn.1.B' \
  44. *** ./LAST/admin.c    Fri Oct  5 19:07:02 1990
  45. --- admin.c    Thu Nov  1 20:40:38 1990
  46. ***************
  47. *** 58,64 ****
  48.           putchar(NL);
  49.           if (exec_chdir_to != NULL)
  50.               printf("\n\rDirectory: %s", exec_chdir_to);
  51. !         run_shell((char *)NULL, 0);
  52.           } else
  53.           printf("%c\n\n\r", c);
  54.       } while (c == '!');
  55. --- 58,64 ----
  56.           putchar(NL);
  57.           if (exec_chdir_to != NULL)
  58.               printf("\n\rDirectory: %s", exec_chdir_to);
  59. !         run_shell((char *)NULL, 0, 0);
  60.           } else
  61.           printf("%c\n\n\r", c);
  62.       } while (c == '!');
  63. *** ./LAST/answer.c    Tue Sep 18 12:44:50 1990
  64. --- answer.c    Tue Nov  6 17:55:29 1990
  65. ***************
  66. *** 422,431 ****
  67.   
  68.       if (distr == NULL) distr = "default";
  69.       var_options(&distr, "always\0ask\0same\0default\0", &opts);
  70. !     always = (opts & FLAG(0));
  71. !     ask = (opts & FLAG(1));
  72. !     same = (opts & FLAG(2));
  73. !     dflt = (opts & FLAG(3));
  74.       
  75.       if (*distr == NUL || dflt) distr = dd;
  76.       
  77. --- 422,431 ----
  78.   
  79.       if (distr == NULL) distr = "default";
  80.       var_options(&distr, "always\0ask\0same\0default\0", &opts);
  81. !     always = (opts & FLAG(1));
  82. !     ask = (opts & FLAG(2));
  83. !     same = (opts & FLAG(3));
  84. !     dflt = (opts & FLAG(4));
  85.       
  86.       if (*distr == NUL || dflt) distr = dd;
  87.       
  88. ***************
  89. *** 893,899 ****
  90.           if (display_group_list(*str == '/'))
  91.           must_redraw = 2;
  92.           else
  93. !         msg("No group list is avaialbe");
  94.           goto again_group;
  95.       }
  96.       if (*str == NUL) {
  97. --- 893,899 ----
  98.           if (display_group_list(*str == '/'))
  99.           must_redraw = 2;
  100.           else
  101. !         msg("No group list is available");
  102.           goto again_group;
  103.       }
  104.       if (*str == NUL) {
  105. *** ./LAST/aux.sh    Fri Oct  5 19:07:02 1990
  106. --- aux.sh    Wed Oct 31 13:07:50 1990
  107. ***************
  108. *** 208,217 ****
  109.       ;;
  110.   
  111.     r*)
  112. !     ${AWK} 'END{printf "Edit original file: (y) "}' < /dev/null
  113.       read act
  114.       case "$act" in
  115. !     ""|"y*") cp $COPY $WORK ;;
  116.       esac
  117.       FIRST_ACTION=edit
  118.       ;;
  119. --- 208,217 ----
  120.       ;;
  121.   
  122.     r*)
  123. !     ${AWK} 'END{printf "Undo all changes? (n) "}' < /dev/null
  124.       read act
  125.       case "$act" in
  126. !     "[yY]*") cp $COPY $WORK ;;
  127.       esac
  128.       FIRST_ACTION=edit
  129.       ;;
  130. *** ./LAST/conf/m-i80386.h    Sat Mar 31 23:12:49 1990
  131. --- conf/m-i80386.h    Sat Nov  3 00:27:14 1990
  132. ***************
  133. *** 16,22 ****
  134. --- 16,24 ----
  135.   
  136.   #undef NETWORK_BYTE_ORDER    /* THEY ARE NOT */
  137.   
  138. + /*
  139.   YOU LOSE -- I DON'T KNOW HOW TO DO THIS ON 80386 BASED SYSTEMS!
  140. + */
  141.   
  142.   #define htonl(l)    ...    /* host long to network long */
  143.   #define ntohl(l)    ...    /* network long to host long */
  144. *** ./LAST/db.c    Fri Oct  5 19:07:04 1990
  145. --- db.c    Wed Nov  7 12:29:18 1990
  146. ***************
  147. *** 979,985 ****
  148.   
  149.       fseek(index, get_index_offset(gh, art_num), 0);
  150.       if (!db_read_offset(index, &data_offset))
  151. !     return (off_t)(-1);
  152.   
  153.       fclose(index);
  154.   
  155. --- 979,985 ----
  156.   
  157.       fseek(index, get_index_offset(gh, art_num), 0);
  158.       if (!db_read_offset(index, &data_offset))
  159. !     data_offset = (off_t)(-1);
  160.   
  161.       fclose(index);
  162.   
  163. *** ./LAST/doc/RELEASE_NOTES    Fri Oct  5 19:07:07 1990
  164. --- doc/RELEASE_NOTES    Tue Nov  6 17:55:27 1990
  165. ***************
  166. *** 1225,1231 ****
  167. --- 1225,1331 ----
  168.   From:    olson%anchor.esd@sgi.com (Dave Olson) + fixes
  169.   Fixed:    Patch #11 [nntp.c global.c]
  170.   
  171. + Prog:    nn
  172. + Title:    "line-1" can be bound in show mode but it is not defined.
  173. + From:    Jaap Vermeulen <jaap%sequent@relay.eu.net>
  174. + Fixed:    Patch #12 [keymap.c]
  175. + Prog:    nn manual
  176. + Title:    A ".nf" is missing
  177. + From:    marcel@duteca.tudelft.nl (Marcel J.E. Mol)
  178. + Fixed:    Patch #12 [nn.1]
  179. + Prog:    nn
  180. + Title:    The var_options function uses (and returns) FLAG(0) which is illegal.
  181. + From:    mmitchel@digi.lonestar.org (Mitch Mitchell)
  182. + Fixed:    Patch #12 [answer.c variable.c]
  183. + Prog:    aux
  184. + Title:    r)eedit should explain better what it does and have default (n).
  185. + From:    coleman@CS.UCLA.EDU (Michael Coleman)
  186. + Fixed:    Patch #12 [aux.sh]
  187. + Prog:    nn
  188. + Title:    ":!shell command" doesn't allow spaces anymore?
  189. + From:    dm@everexn.com (Dan McMullen)
  190. + Fixed:    Patch #12 [init.c]
  191. + Prog:    nnmaster
  192. + Title:    nntp problems should not be mailed to the sysop.
  193. + From:    srp@cgl.ucsf.edu (Scott R. Presnell)
  194. + Fixed:    Patch #12 [global.c master.c nnmaster.8]
  195. +     Default, they are still mailed to the sysop, but repeated
  196. +     messages are ignored (also in the log).  Warning mail can be
  197. +     disabled with -M1 and all error mail can be disabled with -M0.
  198. + Prog:    m-i80386.h
  199. + Title:    contain a single ' which annoys GCC (and ansi C).
  200. + From:    Steven List <itkin@guinan.transact.com>
  201. + Fixed:    Patch #12 [m-i80386.h]
  202. + Prog:    nn
  203. + Title:    if newsgroups file is not found of nntp server, multiple
  204. +     attempts to connect to the server will be done.
  205. + From:    erf@progress.COM (Eric Feigenson)
  206. +     John R MacMillan <john@scocan.sco.com>
  207. + Fixed:    Patch #12 [nntp.c]
  208. +     This was really an NNTP bug, since the server returns a fatal error if
  209. +     the newsgroups file doesn't exist (it reuses code from LIST ACTIVE
  210. +     where it is a fatal error if the file is not found).
  211. + Prog:    nn
  212. + Title:    Text search should work if rot13 decrypting is active
  213. + From:    David Lesher <wb8foz@mthvax.cs.miami.edu>
  214. + Fixed:    Patch #12 [more.c]
  215. + Prog:    nn
  216. + Title:    /RE will only highlight the first occurrence on a line.
  217. + From:    david@wraith.cs.uow.edu.au (David E A Wilson) + fix
  218. + Fixed:    Patch #12 [more.c]
  219. + Prog:    nn
  220. + Title:    nn -g exits when the (j)ump option is used.
  221. + From:    david@wraith.cs.uow.edu.au (David E A Wilson)
  222. + Fixed:    Patch #12 [group.c]
  223.   
  224. + Prog:    xmakefile
  225. + Title:    cvt-help and usercheck does not depend on config.h
  226. + From:    Tom Dawes-Gamble <tmdg@ti.co.uk>
  227. + Fixed:    Patch #12 [xmakefile]
  228. + Prog:    xmakefile
  229. + Title:    EXTRA_LIB is missing for cvt-help and usercheck 
  230. + From:    Ray Davis <rdavis@connie>
  231. + Fixed:    Patch #12 [xmakefile]
  232. + Prog:    SPLITNN1
  233. + Title:    Some sed versions does not truncate existing files for the w command.
  234. + From:    Ken Laprade <laprade@trantor.harris-atd.com>
  235. + Fixed:    Patch #12 [SPLITNN1]
  236. + Prog:    makefile
  237. + Title:    make clean should remove nn.1
  238. + From:    Paul Pomes <paul@uxc.cso.uiuc.edu>
  239. + Fixed:    Patch #12 [xmakefile]
  240. + Prog:    nn
  241. + Title:    In merged groups, confirm-junk-seen requires conf. for every group 
  242. + From:    itkin@mrspoc.Transact.COM (Steven M. List)
  243. + Fixed:    Patch #12 [group.c newsrc.c]
  244. + Prog:    nn
  245. + Title:    .rnlast was not ignored if new .newsrc is created
  246. + From:    mason@freedom.msfc.nasa.gov (Jim Mason)
  247. + Fixed:    Patch #12 [newsrc.c]
  248. + Prog:    nn
  249. + Title:    Typo in "No group list is avaialbe"
  250. + From:    itkin@guinan.transact.com (Steven List)
  251. + Fixed:    Patch #12 [answer.c]
  252.   New features since initial 6.4.0 release
  253.   ----------------------------------------
  254.   
  255. ***************
  256. *** 1635,1637 ****
  257. --- 1735,1773 ----
  258.       rewritten even if the directory is read only.  The backup folder is
  259.       retained if the keep-backup-folder variable is set.  A trace of the
  260.       compression process is now shown if trace-folder-packing is set.
  261. + Prog:    nn
  262. + Title:    Several new "on condition" constructs and other init file goodies.
  263. + From:    KFS (following several requests for rather specific features).
  264. + Added:    Patch #12 [init.c nn.1]
  265. +     Instead of a steady flow of requests for new controls in the init
  266. +     file I decided to take a more generic approach and provide the
  267. +     following new commands and conditionals in the init file.  See
  268. +     the manual for more details.
  269. +         on [ test ]
  270. +         on `shell command` str1 str2 ...
  271. +         on `` str1 str2 ...
  272. +         on !shell command
  273. +         on $VAR [ str1 str2 ... ]
  274. +         else
  275. +         echo MESSAGE
  276. +         error MESSAGE
  277. +         exit [ n ]
  278. +         stop
  279. +         chain alternative-init-file
  280. + Prog:    nn
  281. + Title:    nn can now enter the group that was active the last time nn was quit.
  282. + From:    KFS on many requests
  283. + Added:    Patch #12 [nn.c variable.c]
  284. +     There is a new variable 'enter-last-read-mode' to control this:
  285. +     0: never enter the last group read,
  286. +     1: ask to enter group if it has unread articles, else don't enter,
  287. +     2: ask to enter group even if no unread,
  288. +     3: enter unconditionally if unread articles, else don't enter,
  289. +     4: enter uncond even if no unread.
  290. +     If there are no unread articles, nn will actually locate the next
  291. +     group in the sequence starting with the remembered group.
  292. +     
  293. *** ./LAST/execute.c    Mon Jun 25 15:46:39 1990
  294. --- execute.c    Thu Nov  1 20:40:37 1990
  295. ***************
  296. *** 11,16 ****
  297. --- 11,17 ----
  298.   
  299.   export int shell_restrictions = 0;    /* disable shell escapes */
  300.   
  301. + export char *init_shell = SHELL;
  302.   export char *user_shell;
  303.   export char *exec_chdir_to = NULL;
  304.   
  305. ***************
  306. *** 90,102 ****
  307.       if (cmd == NULL) return !first;
  308.   
  309.       if (*cmd == NUL) {
  310. !         if (first) run_shell((char *)NULL, 1);
  311.           return 1;
  312.       }
  313.   
  314.       strcpy(command, cmd);
  315.   
  316. !     if (!run_shell(command, first)) return !first;
  317.       first = 0;
  318.       prompt_line = -1;
  319.       }
  320. --- 91,103 ----
  321.       if (cmd == NULL) return !first;
  322.   
  323.       if (*cmd == NUL) {
  324. !         if (first) run_shell((char *)NULL, 1, 0);
  325.           return 1;
  326.       }
  327.   
  328.       strcpy(command, cmd);
  329.   
  330. !     if (run_shell(command, first, 0) < 0) return !first;
  331.       first = 0;
  332.       prompt_line = -1;
  333.       }
  334. ***************
  335. *** 110,126 ****
  336.       (char *)NULL
  337.   };
  338.   
  339. ! run_shell(command, clear)
  340.   char *command;
  341.   int clear; /* -2 => no command output (:!!command) - keep visual,
  342.             output before command: -1 => none, 0 => CR/NL, 1 => clear */
  343.   {
  344.       char cmdstring[512];
  345.   
  346. !     if (shell_check()) return 0;
  347.   
  348.       if (command != NULL) {
  349. !     if (!expand_file_name(cmdstring, command, 1)) return 0;
  350.       exec_sh_args[1] = "-c";
  351.           exec_sh_args[2] = cmdstring;
  352.       } else {
  353. --- 111,128 ----
  354.       (char *)NULL
  355.   };
  356.   
  357. ! run_shell(command, clear, init_sh)
  358.   char *command;
  359.   int clear; /* -2 => no command output (:!!command) - keep visual,
  360.             output before command: -1 => none, 0 => CR/NL, 1 => clear */
  361. + int init_sh;    /* 0 => use user_shell, else use init_shell */
  362.   {
  363.       char cmdstring[512];
  364.   
  365. !     if (shell_check()) return -1;
  366.   
  367.       if (command != NULL) {
  368. !     if (!expand_file_name(cmdstring, command, 1)) return -1;
  369.       exec_sh_args[1] = "-c";
  370.           exec_sh_args[2] = cmdstring;
  371.       } else {
  372. ***************
  373. *** 136,143 ****
  374.       putchar(NL);
  375.       }
  376.   
  377. !     execute(user_shell, exec_sh_args, clear == -2 ? 0 : 1);
  378. !     return 1;
  379.   }
  380.   
  381.   #ifndef HAVE_JOBCONTROL
  382. --- 138,145 ----
  383.       putchar(NL);
  384.       }
  385.   
  386. !     return execute(init_sh ? init_shell : user_shell,
  387. !            exec_sh_args, clear == -2 ? 0 : 1);
  388.   }
  389.   
  390.   #ifndef HAVE_JOBCONTROL
  391. *** ./LAST/global.c    Fri Oct  5 19:07:09 1990
  392. --- global.c    Wed Oct 31 23:24:29 1990
  393. ***************
  394. *** 48,53 ****
  395. --- 48,54 ----
  396.   export int process_id;
  397.   export int who_am_i;
  398.   export int dont_write_console = 0;
  399. + export int mail_errors_mode = 2;
  400.   
  401.   #ifdef HAVE_MULTIGROUP
  402.   #ifndef NGROUPS
  403. ***************
  404. *** 671,676 ****
  405. --- 672,686 ----
  406.       FILE *f;
  407.       char cmd[FILENAME*2];
  408.   
  409. +     switch (mail_errors_mode) {
  410. +      case 0:
  411. +     return;
  412. +      case 1:
  413. +     if (!isfatal) return;
  414. +      default:
  415. +     break;
  416. +     }
  417. +     
  418.   #ifdef FATAL_ERROR_MAIL_CMD
  419.       strcpy(cmd, FATAL_ERROR_MAIL_CMD);
  420.   #else
  421. ***************
  422. *** 736,750 ****
  423.       char buf[512];
  424.       char *fmt;
  425.       FILE *f;
  426.       use_vararg;
  427.   
  428.       start_vararg;
  429. !     enter_log('R', va_args1toN);
  430.       end_vararg;
  431.   
  432.       start_vararg;
  433. !     fmt = va_arg1(char *);
  434. !     vsprintf(buf, fmt, va_args2toN);
  435.       end_vararg;
  436.   
  437.       if (who_am_i != I_AM_MASTER)
  438. --- 746,767 ----
  439.       char buf[512];
  440.       char *fmt;
  441.       FILE *f;
  442. +     static char *last_err = NULL;
  443.       use_vararg;
  444.   
  445.       start_vararg;
  446. !     fmt = va_arg1(char *);
  447. !     vsprintf(buf, fmt, va_args2toN);
  448.       end_vararg;
  449.   
  450. +     if (last_err != NULL) {
  451. +     if (strcmp(last_err, buf) == 0) return;
  452. +     free(last_err);
  453. +     }
  454. +     last_err = copy_str(buf);
  455.       start_vararg;
  456. !     enter_log('R', va_args1toN);
  457.       end_vararg;
  458.   
  459.       if (who_am_i != I_AM_MASTER)
  460. *** ./LAST/group.c    Fri Oct  5 19:07:10 1990
  461. --- group.c    Fri Nov  2 19:39:20 1990
  462. ***************
  463. *** 188,193 ****
  464. --- 188,194 ----
  465.       extern flag_type parse_access_flags();
  466.       article_number o_entry_first;
  467.       int o_only_unread;
  468. +     import rc_merged_groups_hack;
  469.   
  470.   #define    menu_return(cmd) { menu_cmd = (cmd); goto menu_exit; }
  471.   
  472. ***************
  473. *** 357,364 ****
  474. --- 358,368 ----
  475.       if (n) sort_articles(0);
  476.       n = 0;
  477.       update_rc(gh);
  478. +     rc_merged_groups_hack = 1;
  479.       } while (mg_head != NULL && (gh = gh->merge_with) != NULL);
  480.   
  481. +     rc_merged_groups_hack = 0;
  482.       killed_articles = o_killed;
  483.       entry_first_article = o_entry_first;
  484.       only_unread_articles = o_only_unread;
  485. ***************
  486. *** 734,739 ****
  487. --- 738,747 ----
  488.       if (gh == orig_group || gh->unread_count <= 0) {
  489.           msg("Cannot jump - no unread articles");
  490.           goto_return(ME_NO_REDRAW);
  491. +     }
  492. +     if (orig_group == NULL) {    /* nn -g */
  493. +         first = -1;
  494. +         goto enter_new_level;
  495.       }
  496.       jump_to_group = gh;
  497.       goto_return(ME_QUIT);
  498. *** ./LAST/init.c    Fri Oct  5 19:07:10 1990
  499. --- init.c    Fri Nov  2 23:29:58 1990
  500. ***************
  501. *** 122,127 ****
  502. --- 122,129 ----
  503.   }
  504.   
  505.   #define START_SEQUENCE 555
  506. + #define CHAIN_FILE 556        /* chain file */
  507. + #define STOP_FILE 557        /* stop */
  508.   
  509.   static load_init_file(name, seq_hook_ptr, only_seq)
  510.   char *name;
  511. ***************
  512. *** 141,146 ****
  513. --- 143,149 ----
  514.       *cmd = NUL;
  515.       name = cmdbuf;
  516.   
  517. +  chain_file:
  518.       if (strchr(name, '/') == NULL)
  519.       name = relative(nn_directory, name);
  520.   
  521. ***************
  522. *** 154,160 ****
  523.           return;
  524.       }
  525.       /* we use AC_REDRAW to avoid !-commands clear the screen */
  526. !     if (parse_command(cmdbuf, AC_REDRAW, init) == START_SEQUENCE) {
  527.           if (seq_hook_ptr) {
  528.           *seq_hook_ptr = init;
  529.           return;    /* no close !! */
  530. --- 157,174 ----
  531.           return;
  532.       }
  533.       /* we use AC_REDRAW to avoid !-commands clear the screen */
  534. !     switch (parse_command(cmdbuf, AC_REDRAW, init)) {
  535. !      case CHAIN_FILE:
  536. !         fclose(init);
  537. !         name = argvec[argc];    /* ARGTAIL */
  538. !         if (name == NULL) return;
  539. !         goto chain_file;
  540. !      case STOP_FILE:
  541. !         fclose(init);
  542. !         return;
  543. !      case START_SEQUENCE:
  544.           if (seq_hook_ptr) {
  545.           *seq_hook_ptr = init;
  546.           return;    /* no close !! */
  547. ***************
  548. *** 311,316 ****
  549. --- 325,332 ----
  550.       if (index < 0) return 0;
  551.   
  552.       if (buf) {
  553. +     if (index >= 1 && buf[0] == '!') return -1;    /* :! is special */
  554.       head = buf;
  555.       tail = buf + index;
  556.       alt = help_alt = alt_commands;
  557. ***************
  558. *** 745,751 ****
  559. --- 761,832 ----
  560.   {
  561.       register char *cp;
  562.       char buf[1024];
  563. +     static char *last_cmd_res = NULL;
  564. +     int i;
  565. +     if (ARGTAIL == NULL || *ARGTAIL == NUL) goto on_err;
  566. +     cp = NULL;
  567. +     switch (*ARGTAIL) {
  568. +      case '#':            /* on #... end: skipped (+hack for else) */
  569. +     goto skip_to_end;
  570. +      case '`':            /* on `shell command` str1 str2 ... */
  571. +     {
  572. +         FILE *p;
  573. +         char *cmd = ARGTAIL + 1, *t;
  574. +         if ((cp = strrchr(cmd, '`')) == NULL) goto syntax_err;
  575. +         if ((t = strip_str(cp + 1)) == NULL) goto syntax_err;
  576. +         *cp = NUL;
  577. +         ARGTAIL = t;
  578. +         if (cmd[0]) {
  579. +         buf[0] = NUL;
  580. +         if (p = popen(cmd, "r")) {
  581. +             if (fgets(buf, 1024, p))
  582. +             buf[strlen(buf) - 1] = NUL;
  583. +             pclose(p);
  584. +         }
  585. +         if (last_cmd_res != NULL && strcmp(last_cmd_res, buf)) {
  586. +             free(last_cmd_res);
  587. +             last_cmd_res = NULL;
  588. +         }
  589. +         if (buf[0] == NUL) goto skip_to_end;
  590. +         last_cmd_res = copy_str(buf);
  591. +         }
  592. +         for (i = 1; argv(i) != NULL; i++)
  593. +         if (strcmp(argv(i), last_cmd_res) == 0) return;
  594. +     }
  595. +     goto skip_to_end;
  596. +      case '$':            /* on $VAR [ a b c ... ] */
  597. +     cp = argv(1);
  598. +     if ((cp = getenv(cp+1)) == NULL) goto skip_to_end;
  599. +     if (ARGTAIL == NULL) return;
  600. +     for (i = 2; argv(i) != NULL; i++)
  601. +         if (strcmp(argv(i), cp) == 0) return;
  602. +     goto skip_to_end;
  603. +     
  604. +      case '!':            /* on !shell-command */
  605. +     cp = ARGTAIL + 1;
  606. +     break;
  607. +      case '[':            /* on [ test ] */
  608. +     cp = ARGTAIL + strlen(ARGTAIL) - 1;
  609. +     if (*cp != ']') goto syntax_err;
  610. +     cp = ARGTAIL;
  611. +     break;
  612. +      default:
  613. +     break;
  614. +     }
  615.   
  616. +     if (cp) {
  617. +     if (run_shell(cp, -2, 1) == 0) return;
  618. +     goto skip_to_end;
  619. +     }
  620.       if (argv(1) == NULL) goto on_err;
  621.   
  622.       SWITCH ( argv(1) ) {
  623. ***************
  624. *** 833,841 ****
  625. --- 914,925 ----
  626.       goto on_err;
  627.       }
  628.   
  629. +  skip_to_end:
  630.       while (fgets_multi(buf, 1024, f) != NULL) {
  631.       for (cp = buf; *cp && isascii(*cp) && isspace(*cp); cp++);
  632. +     if (*cp != 'e') continue;
  633.       if (strncmp(cp, "end", 3) == 0) return;
  634. +     if (strncmp(cp, "else", 4) == 0) return;
  635.       }
  636.       init_message("end missing (on %s)", argv(1));
  637.       return;
  638. ***************
  639. *** 842,847 ****
  640. --- 926,935 ----
  641.       
  642.   on_err:
  643.       init_message("on `what'?");
  644. +     return;
  645. + syntax_err:
  646. +     init_message("syntax error: on %s", ARGTAIL);
  647.   }
  648.   
  649.   parse_command(cmd, ok_val, initf)
  650. ***************
  651. *** 856,867 ****
  652.       if (*ARGTAIL == '!') {
  653.       if (ok_val == AC_UNCHANGED) { /* in macro */
  654.           if (ARGTAIL[1] == '!') /* !!cmd => guarantee no output! */
  655. !         run_shell(ARGTAIL+2, -2);
  656.           else
  657. !         run_shell(ARGTAIL+1, -1);
  658.           return ok_val;
  659.       }
  660. !     if (run_shell(ARGTAIL+1, ok_val == AC_PROMPT ? 1 : 0)) {
  661.           any_key(0);
  662.           return AC_REDRAW;
  663.       }
  664. --- 944,955 ----
  665.       if (*ARGTAIL == '!') {
  666.       if (ok_val == AC_UNCHANGED) { /* in macro */
  667.           if (ARGTAIL[1] == '!') /* !!cmd => guarantee no output! */
  668. !         run_shell(ARGTAIL+2, -2, 1);
  669.           else
  670. !         run_shell(ARGTAIL+1, -1, 1);
  671.           return ok_val;
  672.       }
  673. !     if (run_shell(ARGTAIL+1, ok_val == AC_PROMPT ? 1 : 0, in_init) >= 0) {
  674.           any_key(0);
  675.           return AC_REDRAW;
  676.       }
  677. ***************
  678. *** 988,995 ****
  679. --- 1076,1111 ----
  680.           break;
  681.           }
  682.   
  683. +         CASE( "else" ) {
  684. +         ARGTAIL = "#";    /* skip to end */
  685. +         parse_on_to_end(initf);
  686. +         break;
  687. +         }
  688.           CASE( "end" ) {
  689.           break;
  690. +         }
  691. +         CASE( "echo" ) {
  692. +         printf("\r%s\n\r", ARGTAIL);
  693. +         break;
  694. +         }
  695. +         CASE( "error" ) {
  696. +         printf("\r%s\n\r", ARGTAIL);
  697. +         nn_exit(1);
  698. +         }
  699. +         CASE( "exit" ) {
  700. +         nn_exit(ARGTAIL != NULL ? atoi(ARGTAIL) : 0);
  701. +         }
  702. +         CASE( "chain" ) {
  703. +         return CHAIN_FILE;
  704. +         }
  705. +         CASE( "stop" ) {
  706. +         return STOP_FILE;
  707.           }
  708.   
  709.           CASE( "sequence" ) {
  710. *** ./LAST/keymap.c    Thu Jul 19 18:12:15 1990
  711. --- keymap.c    Mon Oct 15 13:33:46 1990
  712. ***************
  713. *** 478,484 ****
  714.       "leave-article",        K_LEAVE_ARTICLE,    K_ONLY_MORE,
  715.       "leave-next",        K_LEAVE_NEXT,        K_ONLY_MORE,
  716.       "line+1",            K_NEXT_LINE,        0,
  717. !     "line-1",            K_PREV_LINE,        0,
  718.       "line=@",            K_GOTO_LINE,        K_ONLY_MORE,
  719.   
  720.       "macro",            K_MACRO,        0,
  721. --- 478,484 ----
  722.       "leave-article",        K_LEAVE_ARTICLE,    K_ONLY_MORE,
  723.       "leave-next",        K_LEAVE_NEXT,        K_ONLY_MORE,
  724.       "line+1",            K_NEXT_LINE,        0,
  725. !     "line-1",            K_PREV_LINE,        K_ONLY_MENU,
  726.       "line=@",            K_GOTO_LINE,        K_ONLY_MORE,
  727.   
  728.       "macro",            K_MACRO,        0,
  729. *** ./LAST/macro.c    Thu Jul 19 18:12:15 1990
  730. --- macro.c    Thu Nov  1 21:06:01 1990
  731. ***************
  732. *** 6,11 ****
  733. --- 6,12 ----
  734.   
  735.   #include "config.h"
  736.   #include "keymap.h"
  737. + #include "menu.h"
  738.   #include "term.h"
  739.   
  740.   export int in_menu_mode = 0;
  741. ***************
  742. *** 472,478 ****
  743.       char buffer[128];
  744.       strcpy(buffer, m->m_string);
  745.       if (macro_debug) { msg(":%s", buffer); user_delay(1); }
  746. !     parse_command(buffer, 0, (FILE *)NULL);
  747.       m = m->m_next;
  748.       }
  749.   }
  750. --- 473,479 ----
  751.       char buffer[128];
  752.       strcpy(buffer, m->m_string);
  753.       if (macro_debug) { msg(":%s", buffer); user_delay(1); }
  754. !     parse_command(buffer, AC_UNCHANGED, (FILE *)NULL);
  755.       m = m->m_next;
  756.       }
  757.   }
  758. *** ./LAST/man/nn.1.A    Tue Sep 18 12:45:02 1990
  759. --- man/nn.1.A    Wed Nov  7 12:29:49 1990
  760. ***************
  761. *** 1111,1122 ****
  762. --- 1111,1163 ----
  763.   .LP
  764.   Articles can optionally be saved in MAIL or MMDF compatible format by
  765.   setting the \fBmail-format\fP and \fBmmdf-format\fP variables.
  766. + These variables only specify the format used when creating a new folder,
  767. + while appending to an existing folder will be done in the format of the
  768. + folder (unless \fBfolder-format-check\fP is false).
  769.   .LP
  770.   \fBRelated variables\fP:
  771.   confirm-append, confirm-create, decode-header-file,
  772.   decode-skip-prefix, default-save-file, folder-save-file,
  773.   edit-patch-command, edit-print-command, edit-unshar-command, folder,
  774. + folder-format-check,
  775.   mail-format, mmdf-format, patch-command, printer, quick-save,
  776.   save-counter, save-counter-offset, save-report,
  777.   suggest-default-save, unshar-command, unshar-header-file.
  778. + .SH FOLDER MAINTENANCE
  779. + When more than one article is saved in a folder, \fInn\fP is able to
  780. + split the folder, and each article in the folder can be treated like
  781. + a separate article.
  782. + .LP
  783. + This means that you can save, decode, reply, follow-up, etc. just as
  784. + with the original article.
  785. + .LP
  786. + You can also \fIcancel\fP (delete) individual articles in a folder
  787. + using the normal \fBC\fP {\fBcancel\fP} command described later.
  788. + When you quit from the folder, you will then be given the option to
  789. + remove the cancelled articles from the folder.
  790. + .LP
  791. + The original folder is saved in a file named `BackupFolder~' in the
  792. + \&.nn directory (see the \fBbackup-folder-path\fP variable) by
  793. + renaming or copying the old folder as appropriate.
  794. + When the folder
  795. + has been compressed, the backup folder will be removed unless the
  796. + variable \fBkeep-backup-folder\fP is set.
  797. + .LP
  798. + If all articles in a folder are cancelled, the folder will be removed
  799. + or truncated to zero length (whatever is allowed by directory and file
  800. + permissions).
  801. + In this case no backup folder is retained even when
  802. + \fBkeep-backup-folder\fP is set!
  803. + .LP
  804. + If the variable \fBtrace-folder-packing\fP is set, \fInn\fP will show
  805. + which articles are kept and which are removed as the folder is
  806. + rewritten.
  807. + .LP
  808. + Folders are rewritten in the format of the original folder, i.e. the
  809. + \fBmail-format\fP and \fBmmdf-format\fP variables are ignored.
  810. + .LP
  811. + \fBRelated variables\fP:
  812. + backup-folder-path,
  813. + keep-backup-folder,
  814. + trace-folder-packing.
  815.   .\" ENDPART A
  816. *** ./LAST/man/nn.1.B    Tue Sep 18 12:45:05 1990
  817. --- man/nn.1.B    Wed Nov  7 12:29:49 1990
  818. ***************
  819. *** 29,34 ****
  820. --- 29,38 ----
  821.   .br
  822.       ~/News/emacs, ~/News/nn, ~/src/shar/nn
  823.   .TP
  824. + \fB~\fP\fIuser\fP\fB/\fP\fIfile\fP
  825. + The \fB~\fP\fIuser\fP part is replaced by the \fIuser\fP's home
  826. + directory as defined in the /etc/passwd file.
  827. + .TP
  828.   \fB|\fP\fIcommand-line\fP
  829.   Instead of writing to a file, the articles are piped to the given
  830.   shell (/bin/sh) command-line.  Each save or write command will create a
  831. ***************
  832. *** 154,159 ****
  833. --- 158,166 ----
  834.   \&\fBF\fP    {\fBfollow\fP}
  835.   Follow-up with an article in the same newsgroup (unless an alternative
  836.   group is specified in the article header).
  837. + The distribution of the follow-up is normally the same as the original
  838. + article, but this can be modified via the \fBfollow-distribution\fP
  839. + variable.
  840.   .TP
  841.   \&\fBM\fP    {\fBmail\fP}
  842.   Mail a letter or
  843. ***************
  844. *** 185,190 ****
  845. --- 192,200 ----
  846.   expression (typically a single word) which will cause \fInn\fP to show
  847.   a (much shorter) list containing only the lines matching the regular
  848.   expression.
  849. +    Normally, you will be prompted for the distribution of the article
  850. + with the default take from \fBdefault-distribution\fP, but this can be
  851. + changed via the \fBpost-distribution\fP variable.
  852.   .LP
  853.   Generally, \fInn\fP will construct a file with a suitable header, optionally
  854.   include a copy of the article in the file with each non-empty line
  855. ***************
  856. *** 239,244 ****
  857. --- 249,255 ----
  858.   .LP
  859.   \fBRelated variables\fP:
  860.   append-signature-mail, append-signature-post, default-distribution,
  861. + follow-distribution, post-distribution,
  862.   edit-response-check, editor, include-art-id, include-full-header,
  863.   included-mark, mail-header, mail-record, mail-script, mailer,
  864.   mailer-pipe-input, news-header, news-record, news-script,
  865. ***************
  866. *** 710,715 ****
  867. --- 721,727 ----
  868.   closed.  In selection mode, you will be prompted for the identifier of
  869.   the article to cancel.  Normal users can only cancel their own
  870.   articles.
  871. + See also the section on folder maintenance.
  872.   .TP
  873.   \&\fBY\fP    {\fBoverview\fP}
  874.   Provide an overview of the groups with unread articles.
  875. ***************
  876. *** 785,790 ****
  877. --- 797,805 ----
  878.   If a value is specified, it will be assigned to the local variable.
  879.   To assign a new value to a boolean variable, the values \fBon\fP and
  880.   \fBoff\fP must be used.
  881. + .TP
  882. + \fB:lock\fP \fIvariable\fP
  883. + Lock the specified \fIvariable\fP so it cannot be modified.
  884.   .TP
  885.   \fB:man\fP
  886.   Call up the online manual.  The manual is presented as a normal folder
  887. *** ./LAST/man/nn.1.C    Fri Oct  5 19:07:12 1990
  888. --- man/nn.1.C    Wed Nov  7 12:29:49 1990
  889. ***************
  890. *** 137,142 ****
  891. --- 137,156 ----
  892.       \fBset\fP \fIvariable key-name\fP
  893.   .br
  894.   .LP
  895. + A variable can be \fIlocked\fP which makes further modification of the
  896. + variable impossible:
  897. + .br
  898. +     \fBlock\fP \fIvariable\fP
  899. + .br
  900. + This can be used in the \fIsetup\fP init file which is loaded
  901. + unconditionally to enforce local conventions or restrictions.  For
  902. + example, to fix the \fBincluded-mark\fP variable to the string ">",
  903. + the following commands can be placed in the setup file:
  904. + .nf
  905. +     \fBset\fP included-mark >
  906. +     \fBlock\fP included-mark
  907. + .fi
  908. + .LP
  909.   The current variable settings can be shown with the
  910.   .B :set
  911.   command:
  912. ***************
  913. *** 148,153 ****
  914. --- 162,168 ----
  915.   \fB:set all\fP
  916.   This will give a listing of all variables.  Modified variables will be
  917.   marked with a `*' and \fIlocal\fP variables will be marked with a `>'.
  918. + A locked variable is marked with a `!'.
  919.   .TP
  920.   \fB:set /\fP\fIregexp\fP
  921.   This will give a listing of all variables whose name matches the given
  922. ***************
  923. *** 241,246 ****
  924. --- 256,270 ----
  925.   contents of these files internally, so the backup variable can be set
  926.   any time if not set on start-up.
  927.   .TP
  928. + \fBbackup-folder-path\fP \fIfile\fP    (string, default "BackupFolder~")
  929. + When removing deleted articles from a folder, this variable defines
  930. + the name of the file where a (temporary) copy of the original folder
  931. + is saved.  If the \fIfile\fP name doesn't contain a `/', the file will
  932. + be located in the .nn directory.  Otherwise the file name is used
  933. + directly as the relative or full path name of the backup file.
  934. + If possible, the old folder will be renamed to the backup folder name;
  935. + otherwise the old folder is copied to the backup folder.
  936. + .TP
  937.   \fBbackup-suffix\fP \fIsuffix\fP    (string, default ".bak")
  938.   The suffix appended to file names to make the corresponding backup
  939.   file name (see \fBbackup\fP).
  940. ***************
  941. *** 255,260 ****
  942. --- 279,292 ----
  943.   subjects, except in connection with auto-kill and auto-select where
  944.   the individual kill file entries specifies this property.
  945.   .TP
  946. + \fBcheck-group-access\fP    (boolean, default false)
  947. + When set, \fInn\fP will perform a check on the readability of a
  948. + group's readability before showing the menu for that group.  Normally,
  949. + this is not necessary since all users traditionally have access to all
  950. + news groups.  Setting (and locking) this variable may be used to limit
  951. + access to a news group via the permissions and ownership of the
  952. + group's spool directory (this will only work for non-NNTP sites).
  953. + .TP
  954.   \fBcollapse-subject\fP \fIoffset\fP    (integer, default 25)
  955.   When set (non-negative), subject lines which are too long to be
  956.   presented in full on the menus will be "collapsed" by removing a
  957. ***************
  958. *** 376,386 ****
  959.   valid uuencoded data.  This allows \fInn\fP to automatically decode
  960.   (multi-part) postings which are both uuencoded and packed with shar.
  961.   .TP
  962. ! \fBdefault-distribution\fP \fIdistr\fP    (string, default not set)
  963.   The distribution to use as the default suggestion when posting
  964. ! articles using the \fBpost\fP command.  If it is not set, the
  965. ! first component of the group name is used as the suggested
  966. ! distribution, e.g. `comp' when posting to comp.whatever.
  967.   .TP
  968.   \fBdefault-kill-select\fP \fI[1]days\fP    (number, default 30)
  969.   Specifies the default action for the \fBK\fP {\fBkill-select\fP}
  970. --- 408,418 ----
  971.   valid uuencoded data.  This allows \fInn\fP to automatically decode
  972.   (multi-part) postings which are both uuencoded and packed with shar.
  973.   .TP
  974. ! \fBdefault-distribution\fP \fIdistr\fP    (string, default "world")
  975.   The distribution to use as the default suggestion when posting
  976. ! articles using the \fBfollow\fP and \fBpost\fP commands if the
  977. ! corresponding \fBfollow-distribution\fP or \fBpost-distribution\fP
  978. ! variable contains the \fBdefault\fP option.
  979.   .TP
  980.   \fBdefault-kill-select\fP \fI[1]days\fP    (number, default 30)
  981.   Specifies the default action for the \fBK\fP {\fBkill-select\fP}
  982. ***************
  983. *** 439,444 ****
  984. --- 471,490 ----
  985.   When saving an article to a file, header lines embedded in the body of
  986.   the article are escaped using this string to make it possible for
  987.   \fInn\fP to split the folder correctly afterwards.
  988. + Header lines are not escaped if this variable is not set.
  989. + .TP
  990. + \fBenter-last-read-mode\fP \fImode\fP    (integer, default 1)
  991. + Normally, \fInn\fP will remember which group is active when you quit,
  992. + and offer to jump directly to this group when you start \fInn\fP the
  993. + next time.  This variable is used to control this behaviour.  The
  994. + following \fImode\fP values are recognized:
  995. + .nf
  996. + 0: Ignore the remembered group (r.g.).
  997. + 1: Enter r.g. if the group is unread (with user confirmation)
  998. + 2: Enter r.g. or first unread group after it in the sequence (w/conf).
  999. + 3: Enter r.g. if the group is unread (no confirmation)
  1000. + 4: Enter r.g. or first unread group after it in the sequence (no conf).
  1001. + .fi
  1002.   .TP
  1003.   \fBentry-report-limit\fP \fIarticles\fP    (integer, default 300)
  1004.   Normally, \fInn\fP will just move the cursor to the upper left corner
  1005. ***************
  1006. *** 486,494 ****
  1007. --- 532,587 ----
  1008.   .I init
  1009.   file.
  1010.   .TP
  1011. + \fBfolder-format-check\fP    (boolean, default true)
  1012. + When saving an article with a full or partial header in an existing
  1013. + folder, \fInn\fP will check the format of the folder to be able to
  1014. + append the article in the proper format.  If this variable is not set,
  1015. + folders are assumed to be in the format specified via the
  1016. + \fBmmdf-format\fP and \fBmail-format\fP variables, and articles are
  1017. + saved in that format without checking.  Otherwise, the \fB*-format\fP
  1018. + variables are only used to determine the format for \fInew\fP folders.
  1019. + .TP
  1020.   \fBfolder-save-file\fP \fIfile\fP    (string, default not set)
  1021.   The default save file used when saving articles \fIfrom\fP a folder.
  1022.   .TP
  1023. + \fBfollow-distribution\fP \fIwords\fP    (string, default see below)
  1024. + This variable controls how the Distribution: header is constructed for
  1025. + a follow-up to an original article.  Its value is a list of
  1026. + \fIwords\fP selected from the following list:
  1027. + .sp 0.5v
  1028. + [ [ \fBalways\fP ] \fBsame\fP ] [ \fBask\fP ]
  1029. + [ \fBdefault\fP | \fIdistribution\fP ]
  1030. + .sp 0.5v
  1031. + This is interpreted in two steps:
  1032. + .br
  1033. + - First the default distribution is determined.  If \fBsame\fP is
  1034. + specified and the original article has a Distribution: header, that
  1035. + header is used.  Else if \fBdefault\fP is specified (or
  1036. + \fIdistribution\fP is omitted), the value of
  1037. + \fBdefault-distribution\fP is used.  And finally, if only a
  1038. + \fIdistribution\fP (any word) is specified that is used as the default.
  1039. + .br
  1040. + - Then if \fBask\fP is specified, the user will be asked to confirm
  1041. + the default distribution or provide another distribution.  However, if
  1042. + \fBalways\fP (and \fBsame\fP) is specified, and the default was taken
  1043. + from the original article's distribution, the original distribution is
  1044. + used \fIwithout\fP confirmation.
  1045. + .br
  1046. + The default value of \fBfollow-distribution\fP is \fBalways\fP
  1047. + \fBsame\fP \fBdefault\fP, i.e. use either the original distribution or
  1048. + the \fBdefault-distribution\fP without confirmation in either case.
  1049. + .TP
  1050. + \fBfrom-line-parsing\fP \fIstrictness\fP    (integer, default 2)
  1051. + Specifies how strict \fInn\fP must parse a "From " line in a folder to
  1052. + recognize it as a mail format message separator line.  The following
  1053. + strictness values determine whether a line starting with "From " will
  1054. + be recognized as a separator line:
  1055. + .nf
  1056. +     0: Always.
  1057. +     1: Line must have at least 8 fields.
  1058. +     2: Line must contain a valid date and time (ctime style).
  1059. + .fi
  1060. + .TP
  1061.   \fBfsort\fP        (boolean, default true)
  1062.   When set, folders are sorted alphabetically according to the subject
  1063.   (and age).
  1064. ***************
  1065. *** 550,555 ****
  1066. --- 643,666 ----
  1067.   program.  Otherwise, the file containing the article will be given as
  1068.   the first (and only) argument to the \fBinews\fP command.
  1069.   .TP
  1070. + \fBinitial-newsrc-file\fP \fIfile\fP    (string, default '.defaultnewsrc')
  1071. + Defines the name of a file which is used as the initial .newsrc file
  1072. + for new users.  The name may be a full path name, or as the default a
  1073. + file name which will be looked for in a number of places:
  1074. + in the standard news lib directory (where it can be shared with other
  1075. + news readers),
  1076. + in nn's lib directory,
  1077. + and in the database directory.
  1078. + Groups which are not present in the initial .newsrc file will be
  1079. + automatically unsubscribed provided \fBnew-group-action\fP is set to a
  1080. + value allowing unsubscribed groups to be omitted from .newsrc.
  1081. + .TP
  1082. + \fBkeep-backup-folder\fP    (boolean, default false)
  1083. + When set, the backup folder (see \fBbackup-folder-path\fP) created
  1084. + when removing deleted articles from a folder is not removed.
  1085. + Notice that a backup folder is not created if all articles are removed
  1086. + from a folder!
  1087. + .TP
  1088.   \fBkeep-unsubscribed\fP        (boolean, default true)
  1089.   When set, unsubscribed groups are kept in .newsrc.  If not set,
  1090.   \fInn\fP will automatically remove all unsubscribed from .newsrc if
  1091. ***************
  1092. *** 563,568 ****
  1093. --- 674,681 ----
  1094.   \fBkill-debug\fP        (boolean, default false)
  1095.   When set, \fInn\fP will display a trace of the auto-kill/select
  1096.   process on entry to a group.
  1097. + It is automatically turned off if `q' is entered as the answer to a
  1098. + "hit any key" prompt during the debug output.
  1099.   .TP
  1100.   \fBkill-key\fP \fIkey\fP    (key, default tty kill key)
  1101.   The key which deletes the current line
  1102. ***************
  1103. *** 606,611 ****
  1104. --- 719,727 ----
  1105.   \fBmail-format\fP    (boolean, default false)
  1106.   When set, \fInn\fP will save articles in a format that is compatible
  1107.   with normal mail folders.
  1108. + Unless \fBfolder-format-check\fP is false, it is only used to specify
  1109. + the format used when new folders are created.
  1110. + This variable is ignored if \fBmmdf-format\fP is set.
  1111.   .TP
  1112.   \fBmail-header\fP \fIheaders\fP    (string, default not set)
  1113.   The \fIheaders\fP string specifies one or more extra header lines
  1114. ***************
  1115. *** 685,690 ****
  1116. --- 801,808 ----
  1117.   .TP
  1118.   \fBmmdf-format\fP    (boolean, default false)
  1119.   When set, \fInn\fP will save articles in MMDF format.
  1120. + Unless \fBfolder-format-check\fP is false, it is only used to specify
  1121. + the format used when new folders are created.
  1122.   .TP
  1123.   \fBmonitor\fP        (boolean, default false)
  1124.   When set, \fInn\fP will show
  1125. ***************
  1126. *** 808,813 ****
  1127. --- 926,952 ----
  1128.   \fBpatch-command\fP \fIshell-command\fP    (string, default "patch -p0")
  1129.   This is the command which is invoked by the \fB:patch\fP command.
  1130.   .TP
  1131. + \fBpost-distribution\fP \fIwords\fP    (string, default see below)
  1132. + This variable controls how the Distribution: header is constructed
  1133. + when posting an original article.  Its value is a list of
  1134. + \fIwords\fP selected from the following list:
  1135. + .sp 0.5v
  1136. + [ \fBask\fP ] [ \fBdefault\fP | \fIdistribution\fP ]
  1137. + .sp 0.5v
  1138. + This is interpreted in two steps:
  1139. + .br
  1140. + - First the default distribution is determined.  If \fBdefault\fP is
  1141. + specified (or \fIdistribution\fP is omitted), the value of
  1142. + \fBdefault-distribution\fP is used.  Otherwise, the specified
  1143. + \fIdistribution\fP (any word) is used as the default.
  1144. + .br
  1145. + - Then if \fBask\fP is specified, the user will be asked to confirm
  1146. + the default distribution or provide another distribution.
  1147. + .br
  1148. + The default value of \fBpost-distribution\fP is \fBask\fP
  1149. + \fBdefault\fP, i.e. use the \fBdefault-distribution\fP with
  1150. + confirmation from the user.
  1151. + .TP
  1152.   \fBpreview-continuation\fP \fIcond\fP    (integer, default 12)
  1153.   This variable determines on what terms the following article should be
  1154.   automatically shown when previewing an article, and the
  1155. ***************
  1156. *** 1147,1152 ****
  1157. --- 1286,1295 ----
  1158.   This is useful on systems without a
  1159.   .I sysline (1)
  1160.   utility.
  1161. + .TP
  1162. + \fBtrace-folder-packing\fP    (boolean, default true)
  1163. + When set, a trace of the retained and deleted messages is printed when
  1164. + a folder is rewritten.
  1165.   .TP
  1166.   \fBtrusted-escape-codes\fP \fIcodes\fP    (string, default none)
  1167.   When set to a list of one or more characters, \fInn\fP will trust and
  1168. *** ./LAST/man/nn.1.D    Thu Jul 19 18:12:17 1990
  1169. --- man/nn.1.D    Wed Nov  7 12:29:49 1990
  1170. ***************
  1171. *** 164,169 ****
  1172. --- 164,170 ----
  1173.   .TP
  1174.   \-\fBI\fP
  1175.   Do not read the init file.  This must be the first option!!
  1176. + The global \fIsetup\fP file is still read.
  1177.   .TP
  1178.   \-\fBI\fP\fIfile-list\fP
  1179.   Specifies an alternate list of init files to be loaded instead of the
  1180. ***************
  1181. *** 174,179 ****
  1182. --- 175,182 ----
  1183.   \fInot\fP be separated from the \fB\-I\fP option by blanks, and it
  1184.   must be the first option.  Example:  The default behaviour corresponds
  1185.   to using -I,init (first the global file, then the file ~/.nn/init).
  1186. + The global \fIsetup\fP file is still read as the first init file
  1187. + independently of the -I option used.
  1188.   .TP
  1189.   \-\fBk\fP    {\fBtoggle kill\fP}
  1190.   Do not [do] perform automatic kill and selection of articles.
  1191. ***************
  1192. *** 408,413 ****
  1193. --- 411,417 ----
  1194.       ?no return # and old prompt is restored
  1195.       read-skip       # changes the prompt
  1196.       \fBprompt\fP "" # so forget old prompt
  1197. + .fi
  1198.   .TP
  1199.   \fBecho\fP \fIstring\fP
  1200.   Display the \fIstring\fP in the prompt line for a short period.  Example:
  1201. ***************
  1202. *** 652,658 ****
  1203.   .ta \w'continue-no-mark'u+5m +\w'Selection_mode'u+3m
  1204.   .\"ta 4 26 42
  1205.   .br
  1206. ! \fIFunction    Selection mode    Reading mode
  1207.   .br
  1208.   \fBadvance-article\fP    \fBnix\fP     a
  1209.   .br
  1210. --- 656,662 ----
  1211.   .ta \w'continue-no-mark'u+5m +\w'Selection_mode'u+3m
  1212.   .\"ta 4 26 42
  1213.   .br
  1214. ! \fIFunction    Selection mode    Reading mode\fP
  1215.   .br
  1216.   \fBadvance-article\fP    \fBnix\fP     a
  1217.   .br
  1218. ***************
  1219. *** 797,807 ****
  1220.   .SH THE INIT FILES
  1221.   The
  1222.   .I init
  1223. ! files are used to customize \fInn\fP's behaviour to your personal taste.
  1224. ! \fINn\fP uses two init files \- a system-wide init file located in the
  1225. ! library directory, and a private init file located in the user's
  1226. ! \&\fI.nn\fP directory.  The private init file is read after the global
  1227. ! init file to allow the user to change the default setup.
  1228.   .LP
  1229.   The init file is parsed one line at a time.  If a line ends with a
  1230.   backslash `\e', the backslash is ignored, and the following line is
  1231. --- 801,826 ----
  1232.   .SH THE INIT FILES
  1233.   The
  1234.   .I init
  1235. ! files are used to customize \fInn\fP's behaviour to local conventions
  1236. ! and restrictions and to satisfy each user's personal taste.
  1237. ! .br
  1238. ! Normally, \fInn\fP reads upto three init files on start-up if they
  1239. ! exist (all init files are optional):
  1240. ! .TP
  1241. ! $LIB/\fBsetup\fP
  1242. ! A system-wide file located in the library directory.  This file is
  1243. ! \fIalways\fP loaded before any other init file (even when the
  1244. ! \-\fBI\fP option is specified).  It cannot contain a group
  1245. ! presentation sequence.
  1246. ! .TP
  1247. ! $LIB/\fBinit\fP
  1248. ! Another system-wide (global) init file located in the library
  1249. ! directory.  This file may be ignored via the \-\fBI\fP option.
  1250. ! .TP
  1251. ! ~/.nn/\fBinit\fP
  1252. ! The private init file located in the user's \&\fI.nn\fP directory.
  1253. ! It is read after the global init file to allow the user to change the
  1254. ! default setup.
  1255.   .LP
  1256.   The init file is parsed one line at a time.  If a line ends with a
  1257.   backslash `\e', the backslash is ignored, and the following line is
  1258. ***************
  1259. *** 831,836 ****
  1260. --- 850,858 ----
  1261.   and
  1262.   .B :unset
  1263.   commands described earlier (except that the : prefix is omitted.)
  1264. + .sp 0.5v
  1265. + Variables can also be locked via the \fBlock\fP command; this is
  1266. + typically done in the \fIsetup\fP file to enforce local policies.
  1267.   .TP
  1268.   .B Key mappings
  1269.   You can use all the versions of the
  1270. ***************
  1271. *** 868,873 ****
  1272. --- 890,927 ----
  1273.       load init.@
  1274.   .fi
  1275.   .TP
  1276. + .B Switch to loading a different init file
  1277. + You can skip the rest of the current init file and start loading a
  1278. + different init file with the following command:
  1279. + .sp 0.5v
  1280. +     \fBchain\fP \fIfile\fP
  1281. + .sp 0.5v
  1282. + If this occur in the private or global init file, the chained init
  1283. + file may contain a sequence part which will replace the private or
  1284. + global presentation sequence respectively.
  1285. + .TP
  1286. + .B Stop loading current init file
  1287. + You can skip the rest of the current init file with the following
  1288. + command:
  1289. + .sp 0.5v
  1290. +     \fBstop\fP
  1291. + .TP
  1292. + .B Give error messages and/or terminate
  1293. + If an error is detected in the init file, the following commands can be
  1294. + used to print an error message and/or terminate execution:
  1295. + .sp 0.5v
  1296. + \fBerror\fP \fIfatal error message\fP...
  1297. + .br
  1298. +     Print the message and terminate execution.
  1299. + .sp 0.5v
  1300. + \fBecho\fP \fIwarning message\fP...
  1301. + .br
  1302. +     Print the message and continue.
  1303. + .sp 0.5v
  1304. + \fBexit\fP [ \fIstatus\fP ]
  1305. + .br
  1306. +     Terminate \fInn\fP with the specified exit status or 0 if omitted.
  1307. + .TP
  1308.   .B Change working directory of nn
  1309.   You can use the
  1310.   .B cd
  1311. ***************
  1312. *** 924,939 ****
  1313.   several times during the \fInn\fP session.
  1314.   .LP
  1315.   A command group begins with the word \fBon\fP and
  1316. ! ends with the word \fBend\fP.  The \fBon\fP symbol must followed by
  1317. ! one of the following identifiers denoting when the group is executed:
  1318.   .sp 0.5v
  1319. ! .nf
  1320. !     \fBon\fP ...
  1321. !     commands
  1322. !     \fBend\fP
  1323.   .fi
  1324. - .sp 0.5v
  1325. - The following command groups may be defined:
  1326.   .TP
  1327.   \fBon slow\fP
  1328.   .br
  1329. --- 978,1061 ----
  1330.   several times during the \fInn\fP session.
  1331.   .LP
  1332.   A command group begins with the word \fBon\fP and
  1333. ! ends with the word \fBend\fP.  The following command groups are
  1334. ! conditionally executed during the parsing of the init file if the
  1335. ! specified \fIcondition\fP is true.  They may also have an optional
  1336. ! \fBelse\fP part which is executed if the \fIcondition\fP is false:
  1337.   .sp 0.5v
  1338. ! .nf
  1339. !     \fBon\fP \fIcondition\fP
  1340. !         commands
  1341. !     [ \fBelse\fP
  1342. !         commands ]
  1343. !     \fBend\fP
  1344. ! .fi
  1345. ! .LP
  1346. ! The following conditional command groups may be used in the init file
  1347. ! to be executed at start-up:
  1348. ! .TP
  1349. ! \fBon [\fP \fItest\fP \fB]\fP
  1350. ! The commands (init file syntax) in the group are executed only if the
  1351. ! specified \fItest\fP is true.
  1352. ! A shell is spawned to execute the command "[ \fItest\fP ]", so all the
  1353. ! options of the \fBtest\fP(1) command is available.  For example, to
  1354. ! unset the flow-control variable if the tty is a pseudo-tty, the
  1355. ! following conditional can be used:
  1356. ! .nf
  1357. !     on [ -n "`tty | grep ttyp`" ]
  1358. !         unset flow-control
  1359. !     end
  1360. ! .fi
  1361. ! .TP
  1362. ! \fBon !\fP\fIshell command\fP
  1363. ! The command group is executed if the given \fIshell command\fP exits
  1364. ! with 0 status (success).
  1365. ! Care should be taken that the command does not produce any
  1366. ! output, e.g. by redirecting its output to /dev/null.  For example, to
  1367. ! prevent people from reading news if load is above a specific level,
  1368. ! the following conditional might be placed in the global setup file.
  1369. ! .nf
  1370. !     on !load-above 5
  1371. !         error load is too high, try again later.
  1372. !     end
  1373. ! .fi
  1374. ! .TP
  1375. ! \fBon `\fP\fIshell command\fP\|\fB`\fP \fIstring\fP...
  1376. ! The command group is executed if the \fIfirst output line\fP from
  1377. ! executing the specified \fIshell command\fP is listed among the
  1378. ! specified \fIstring\fP values.  The \fIshell command\fP can be omitted
  1379. ! on subsequent occurrences of this conditional, in which case
  1380. ! the output from the last \fBshell command\fP is used.
  1381. ! For example, the following conditional
  1382. ! can be used to switch to an init file which has a limited sequence for
  1383. ! news reading during working hours, evenings, and nights:
  1384. ! .nf
  1385. !     on `date +%H` 9 10 11 12 13 14 15 16
  1386. !         chain init.work
  1387. !     end
  1388. !     on `` 17 18 19 20 21
  1389. !         chain init.evening
  1390. !     else
  1391. !         chain init.night
  1392. !     end
  1393. ! .fi
  1394. ! .TP
  1395. ! \fBon ``\fP \fIstring\fP...
  1396. ! This is equivalent to the previous form except that instead of
  1397. ! executing a shell command, the output from the previous 
  1398. ! .TP
  1399. ! \fBon $\fP\fIvariable\fP [ \fIvalue\fP ]
  1400. ! If no \fIvalue\fP strings are specified, the command group is executed
  1401. ! if the given \fIvariable\fP is defined in the environment.  Otherwise,
  1402. ! the command group is executed only if the value of the \fIvariable\fP
  1403. ! occur in the \fIvalue\fP list.  For example, if you want \fInn\fP to
  1404. ! look for mail in whatever $MAIL is set to - if it is set - you can use
  1405. ! the following code:
  1406. ! .nf
  1407. !     on $MAIL
  1408. !         set mail $(MAIL)
  1409. !     end
  1410.   .fi
  1411.   .TP
  1412.   \fBon slow\fP
  1413.   .br
  1414. ***************
  1415. *** 974,979 ****
  1416. --- 1096,1105 ----
  1417.   .br
  1418.   The commands are executed if the current program (\fInn\fP,
  1419.   \fInncheck\fP, etc) in the \fIprogram-name\fP list.
  1420. + .LP
  1421. + The following \fBon\fP command groups are really macros which may be
  1422. + executed during \fInn\fP's normal processing, and as such they cannot
  1423. + have an \fBelse\fP part.
  1424.   .TP
  1425.   \fBon entry\fP [ \fIgroup list\fP ]
  1426.   .br
  1427. ***************
  1428. *** 1347,1353 ****
  1429. --- 1473,1483 ----
  1430.   .br
  1431.   ~/.nn/LAST    The time stamp of the last news group we have seen.
  1432.   .br
  1433. + ~/.nn/NEXTG    Active group last time \fInn\fP was quit.
  1434. + .br
  1435.   ~/.nn/.param    Parameter file for the aux script
  1436. + .br
  1437. + $lib/setup    System-wide setup - always read first.
  1438.   .br
  1439.   $lib/init    System-wide setup and presentation sequence.
  1440.   .br
  1441. *** ./LAST/man/nnmaster.8    Mon Jun 25 15:46:47 1990
  1442. --- man/nnmaster.8    Wed Oct 31 22:22:12 1990
  1443. ***************
  1444. *** 180,185 ****
  1445. --- 180,192 ----
  1446.   \fB4\fP:  Recollect all articles on every scan.
  1447.   .br
  1448.   .TP
  1449. + \-\fBM\fP \fImode\fP
  1450. + Normally, \fInnmaster\fP will send a message via mail to the news
  1451. + administrator (OWNER) when an error or potential problems
  1452. + (primarily nntp related) occur.  This can be restricted to only fatal
  1453. + errors (\fInnmaster\fP terminated) if \fImode\fP is 1, and disabled
  1454. + completely if \fImode\fP is 0.
  1455. + .TP
  1456.   \-\fBQ\fP
  1457.   Normally, \fInnmaster\fP will print a message on the system console or
  1458.   in the syslog if a fatal error happens.  This option will prevent
  1459. *** ./LAST/master.c    Tue Sep 18 12:45:07 1990
  1460. --- master.c    Wed Oct 31 23:24:29 1990
  1461. ***************
  1462. *** 60,65 ****
  1463. --- 60,66 ----
  1464.       dont_write_console,
  1465.       expire_method,
  1466.       expire_level,
  1467. +     mail_errors_mode,
  1468.       recollect_method,
  1469.       reread_groups_file,
  1470.       ignore_bad_articles,
  1471. ***************
  1472. *** 127,132 ****
  1473. --- 128,134 ----
  1474.       'k', Bool_Option( kill_running ),
  1475.       'l', String_Option_Optional( lock_message, "" ),
  1476.       'L', String_Option( log_entry_filter ),
  1477. +     'M', Int_Option( mail_errors_mode ),
  1478.       'O', Int_Option( max_age_days ),
  1479.       'Q', Bool_Option( dont_write_console ),
  1480.       'r', Int_Option_Optional( repeat_delay, 10 ),
  1481. *** ./LAST/more.c    Fri Oct  5 19:07:13 1990
  1482. --- more.c    Fri Nov  2 17:38:05 1990
  1483. ***************
  1484. *** 768,774 ****
  1485.           col++;
  1486.           break;
  1487.       }
  1488. !     }
  1489.   
  1490.       *lp++ = c;
  1491.       col++;
  1492. --- 768,776 ----
  1493.           col++;
  1494.           break;
  1495.       }
  1496. !     } else
  1497. !     if (rot13_active && linenum > 0)
  1498. !     c = ROT13_DECODE(c);
  1499.   
  1500.       *lp++ = c;
  1501.       col++;
  1502. ***************
  1503. *** 856,861 ****
  1504. --- 858,869 ----
  1505.           if (lp == match_end) {
  1506.           highlight(0);
  1507.           match_start = NULL;
  1508. +         if (regexec_cf(regular_expr, lp)) {
  1509. +             match_start = regular_expr->startp[0];
  1510. +             match_end = regular_expr->endp[0];
  1511. +             lp--;
  1512. +             continue;
  1513. +          }
  1514.           if (match_redraw) goto no_print;
  1515.           }
  1516.       }
  1517. ***************
  1518. *** 871,878 ****
  1519.           skip_spaces = 1;
  1520.           has_space = 0;
  1521.           }
  1522. -         if (rot13_active && linenum > 0)
  1523. -         c = ROT13_DECODE(c);
  1524.       }
  1525.   
  1526.       putchar(c);
  1527. --- 879,884 ----
  1528. *** ./LAST/newsrc.c    Fri Oct  5 19:07:16 1990
  1529. --- newsrc.c    Mon Nov  5 15:59:30 1990
  1530. ***************
  1531. *** 236,241 ****
  1532. --- 236,244 ----
  1533.       if (no_update) return;
  1534.   
  1535.       if (new_group_action == RCX_RNLAST) {
  1536. +     if (rnlast_line[0] == NULL)
  1537. +         for (i = 0; i < MAX_RNLAST_LINE; i++)
  1538. +         rnlast_line[i] = copy_str("");
  1539.       lf = open_file(rnlast_path, OPEN_CREATE|MUST_EXIST);
  1540.       fputs(rnlast_line[RN_LAST_GROUP_READ], lf);    /* as good as any */
  1541.       fprintf(lf, "%ld\n", (long)cur_time()); /* RN_LAST_TIME_RUN */
  1542. ***************
  1543. *** 340,345 ****
  1544. --- 343,350 ----
  1545.       rc = open_file(newsrc_file, OPEN_READ);
  1546.       if (rc == NULL) {
  1547.       extern FILE *open_file_search_path();
  1548. +     last_new_group = -1;    /* ignore LAST & .rnlast if no .newsrc */
  1549.       rc = open_file_search_path(initial_newsrc_path, OPEN_READ);
  1550.       if (rc == NULL) goto new_user;
  1551.       /* ignore groups not in the initial newsrc file */
  1552. ***************
  1553. *** 995,1006 ****
  1554.    *    sort_articles(0) MUST HAVE BEEN CALLED BEFORE USE.
  1555.    */
  1556.   
  1557.   update_rc(gh)
  1558.   register group_header *gh;
  1559.   {
  1560.       register article_header *ah, **ahp;
  1561.       register article_number art;
  1562. !     register int junk_seen = 0;
  1563.   
  1564.       if (gh->group_flag & (G_FOLDER | G_FAKED)) return;
  1565.   
  1566. --- 1000,1015 ----
  1567.    *    sort_articles(0) MUST HAVE BEEN CALLED BEFORE USE.
  1568.    */
  1569.   
  1570. + export int rc_merged_groups_hack = 0;
  1571.   update_rc(gh)
  1572.   register group_header *gh;
  1573.   {
  1574.       register article_header *ah, **ahp;
  1575.       register article_number art;
  1576. !     static int junk_seen = 0;
  1577. !     if (!rc_merged_groups_hack) junk_seen = 0;
  1578.   
  1579.       if (gh->group_flag & (G_FOLDER | G_FAKED)) return;
  1580.   
  1581. *** ./LAST/nn.c    Tue Sep 18 12:45:10 1990
  1582. --- nn.c    Mon Nov  5 18:27:06 1990
  1583. ***************
  1584. *** 151,157 ****
  1585. --- 151,211 ----
  1586.   }
  1587.   
  1588.   export group_header *jump_to_group = NULL;
  1589. + export int enter_last_read_mode = 1;
  1590.   
  1591. + static group_header *last_group_maint(last, upd)
  1592. + group_header *last;
  1593. + int upd;
  1594. + {
  1595. +     group_header *gh;
  1596. +     FILE *f;
  1597. +     char *lg_file;
  1598. +     char buf[256], *cp;
  1599. +     lg_file = relative(nn_directory, "NEXTG");
  1600. +     if (upd) {
  1601. +     if (last == NULL)
  1602. +         unlink(lg_file);
  1603. +     else {
  1604. +         f = open_file(lg_file, OPEN_CREATE | MUST_EXIST);
  1605. +         fprintf(f, "%s\n", last->group_name);
  1606. +         fclose(f);
  1607. +     }
  1608. +     return NULL;
  1609. +     }
  1610. +     if (enter_last_read_mode == 0) goto none;
  1611. +     f = open_file(lg_file, OPEN_READ);
  1612. +     if (f == NULL) goto none;
  1613. +     
  1614. +     if (fgets(buf, 256, f)) {
  1615. +     if (cp = strchr(buf, NL)) *cp = NUL;
  1616. +     gh = lookup(buf);
  1617. +     }
  1618. +     fclose(f);
  1619. +     if (gh == NULL || gh == last || !(gh->group_flag & G_SEQUENCE))
  1620. +     goto none;
  1621. +     
  1622. +     switch (enter_last_read_mode) {
  1623. +      case 1:        /* confirm if unread, skip if read */
  1624. +     if (gh->unread_count == 0) goto none;
  1625. +      case 2:        /* confirm any case */
  1626. +     prompt_line = Lines-1;
  1627. +     prompt("Enter %s (%ld unread)? ", gh->group_name, gh->unread_count);
  1628. +     if (!yes(0)) goto none;
  1629. +     break;
  1630. +      case 3:        /* enter uncond if unread */
  1631. +     if (gh->unread_count == 0) goto none;
  1632. +      case 4:        /* enter uncond */
  1633. +     break;
  1634. +     }
  1635. +     return gh;
  1636. +  none:
  1637. +     return last;
  1638. + }
  1639.   static read_news(access_mode, mask)
  1640.   flag_type access_mode;
  1641.   char *mask;
  1642. ***************
  1643. *** 160,165 ****
  1644. --- 214,220 ----
  1645.       flag_type group_mode;
  1646.       int menu_cmd;
  1647.       int must_clear = 0, did_jump = 0;
  1648. +     group_header *last_group_read = NULL;
  1649.       extern int menu();
  1650.   
  1651.       prev = group_sequence;
  1652. ***************
  1653. *** 166,173 ****
  1654.       gh = group_sequence;
  1655.       after_loop = NULL;
  1656.   
  1657. !     if (access_mode == 0 && !also_read_articles)
  1658.       m_invoke(-2);
  1659.   
  1660.       for (;;) {
  1661.       group_mode = access_mode;
  1662. --- 221,230 ----
  1663.       gh = group_sequence;
  1664.       after_loop = NULL;
  1665.   
  1666. !     if (access_mode == 0 && !also_read_articles) {
  1667. !     gh = last_group_maint(gh, 0);
  1668.       m_invoke(-2);
  1669. +     }
  1670.   
  1671.       for (;;) {
  1672.       group_mode = access_mode;
  1673. ***************
  1674. *** 201,206 ****
  1675. --- 258,264 ----
  1676.               continue;
  1677.           }
  1678.           }
  1679. +         last_group_read = NULL;
  1680.           break;
  1681.       }
  1682.   
  1683. ***************
  1684. *** 235,240 ****
  1685. --- 293,299 ----
  1686.       }
  1687.   
  1688.       if (menu_cmd != ME_NO_ARTICLES) {
  1689. +         last_group_read = gh;
  1690.           after_loop = NULL;
  1691.           must_clear++;
  1692.       }
  1693. ***************
  1694. *** 242,248 ****
  1695.       switch (menu_cmd) {
  1696.   
  1697.        case ME_QUIT:    /* or jump */
  1698. !         if (!jump_to_group) return must_clear;
  1699.   
  1700.           prev = jump_to_group;
  1701.           jump_to_group = NULL;
  1702. --- 301,307 ----
  1703.       switch (menu_cmd) {
  1704.   
  1705.        case ME_QUIT:    /* or jump */
  1706. !         if (!jump_to_group) goto out;
  1707.   
  1708.           prev = jump_to_group;
  1709.           jump_to_group = NULL;
  1710. ***************
  1711. *** 272,277 ****
  1712. --- 331,341 ----
  1713.           continue;
  1714.       }
  1715.       }
  1716. +  out:
  1717. +     if (access_mode == 0 && !also_read_articles)
  1718. +     last_group_maint(last_group_read, 1);
  1719.       return must_clear;
  1720.   }
  1721.   
  1722. *** ./LAST/nntp.c    Fri Oct  5 19:07:16 1990
  1723. --- nntp.c    Sat Nov  3 00:43:29 1990
  1724. ***************
  1725. *** 460,465 ****
  1726. --- 460,469 ----
  1727.    *    Contains some code to handle server timeouts intelligently.
  1728.    */
  1729.   
  1730. + /* LIST XXX return fatal ERR_FAULT code if requested list does not exist */
  1731. + /* This is only fatal for LIST ACTIVE -- else change to ERR_NOGROUPS */
  1732. + static int fix_list_response = 0;
  1733.   /*VARARGS*/
  1734.   static ask_server(va_alist)
  1735.   va_dcl
  1736. ***************
  1737. *** 467,474 ****
  1738. --- 471,482 ----
  1739.       char buf[NNTP_STRLEN];
  1740.       char *fmt;
  1741.       int response;
  1742. +     int fix_err;
  1743.       use_vararg;
  1744.   
  1745. +     fix_err = fix_list_response;
  1746. +     fix_list_response = 0;
  1747.       start_vararg;
  1748.       fmt = va_arg1(char *);
  1749.       vsprintf(buf, fmt, va_args2toN);
  1750. ***************
  1751. *** 489,494 ****
  1752. --- 497,504 ----
  1753.        * 500-599    Fatal NNTP errors.  Handled below.
  1754.        */
  1755.       if (response == ERR_GOODBYE || response > ERR_COMMAND) {
  1756. +     if (fix_err && response == ERR_FAULT) return ERR_NOGROUP;
  1757.       nntp_failed = 1;
  1758.       nntp_close_server();
  1759.   
  1760. ***************
  1761. *** 818,824 ****
  1762. --- 828,838 ----
  1763.    again:
  1764.       if (!is_connected && connect_server() < 0) goto err;
  1765.   
  1766. +     fix_list_response = 1;
  1767.       switch (n = ask_server("LIST NEWSGROUPS")) {
  1768. +      case ERR_NOGROUP:        /* really ERR_FAULT */
  1769. +     goto err;
  1770.        case OK_GROUPS:
  1771.       if (copy_text(new) == 0) {
  1772.           if (fflush(new) != EOF) break;
  1773. *** ./LAST/patchlevel.h    Fri Oct  5 19:07:17 1990
  1774. --- patchlevel.h    Tue Nov  6 17:55:28 1990
  1775. ***************
  1776. *** 22,28 ****
  1777.    *    1990-07-19: Patch #9 (6.4.9) - MEDIUM
  1778.    *    1990-09-18: Patch #10 (6.4.10) - HIGH
  1779.    *    1990-10-05: Patch #11 (6.4.11) - HIGH
  1780.    */
  1781.   
  1782. ! #define PATCHLEVEL 11
  1783.   
  1784. --- 22,29 ----
  1785.    *    1990-07-19: Patch #9 (6.4.9) - MEDIUM
  1786.    *    1990-09-18: Patch #10 (6.4.10) - HIGH
  1787.    *    1990-10-05: Patch #11 (6.4.11) - HIGH
  1788. +  *    1990-11-07: Patch #12 (6.4.12) - LOW
  1789.    */
  1790.   
  1791. ! #define PATCHLEVEL 12
  1792.   
  1793. *** ./LAST/variable.c    Fri Oct  5 19:07:21 1990
  1794. --- variable.c    Mon Nov  5 16:17:39 1990
  1795. ***************
  1796. *** 8,13 ****
  1797. --- 8,62 ----
  1798.   #include "keymap.h"
  1799.   #include "regexp.h"
  1800.   
  1801. + /*
  1802. +  * Variable types and variants
  1803. +  *
  1804. +  * Boolean: type 'int'.
  1805. +  *
  1806. +  *    BOOL 0        Ordinary boolean variable.
  1807. +  *    BOOL 1        As 0 + redraw screen on return.
  1808. +  *    BOOL 2        Special: reorder menu according to new value.
  1809. +  *    BOOL 4        Inverse boolean varible ("set" clears internal var).
  1810. +  *
  1811. +  * Numeric: type 'int'.
  1812. +  *
  1813. +  *    INT 0        Ordinary numeric variable ("unset" set var to 0).
  1814. +  *    INT 1        As 0 + redraw screen on return.
  1815. +  *    INT 2        As 0, but "unset" set var to -1.
  1816. +  *    INT 3        As 2 + redraw screen on return.
  1817. +  *
  1818. +  * Strings: type 'char *'
  1819. +  *
  1820. +  *    STR 0        Ordinary string ("unset" set var to NULL).
  1821. +  *    STR 2        (home relative) file name or full path.
  1822. +  *            Automatically expanded.  ("unset" set var to NULL).
  1823. +  *    STR 3        Ordinary string, but cannot be "unset".
  1824. +  *    STR 4        (Expanded) file name - cannot be unset.
  1825. +  *
  1826. +  *    CODES n        String initialized by list of key names.
  1827. +  *            A maximum of 16 CODES variables (n = 0 - 15) exist.
  1828. +  *
  1829. +  * Strings: type 'char []'
  1830. +  *
  1831. +  *    STR 1        Ordinary string saved in static array.
  1832. +  *            "unset" set array to empty string.
  1833. +  *            Warning: no bounds checking!
  1834. +  *            Notice: Variable address is "(char **)var"  (no &).
  1835. +  *
  1836. +  * Keys: type 'key_type'
  1837. +  *
  1838. +  *    KEY 0        Ordinary key.
  1839. +  *
  1840. +  * Pseudo variables:
  1841. +  *
  1842. +  *    SPEC n        Treated by V_SPECIAL 'case n'.
  1843. +  *
  1844. +  * Modifiers:
  1845. +  *
  1846. +  *    INIT        Can only be set in init file.
  1847. +  *    SAFE        Cannot be changed if "shell-restrictions" is set.
  1848. +  */
  1849.   import in_init;
  1850.   
  1851.   import char            /* string variables */
  1852. ***************
  1853. *** 81,86 ****
  1854. --- 130,136 ----
  1855.       edit_print_command,
  1856.       edit_unshar_command,
  1857.       empty_answer_check,
  1858. +     enter_last_read_mode,
  1859.       flow_control,
  1860.       flush_typeahead,
  1861.       fmt_rptsubj,
  1862. ***************
  1863. *** 275,280 ****
  1864. --- 325,331 ----
  1865.       "edit-unshar-command",     BOOL 0,        (char **)&edit_unshar_command,
  1866.       "editor",            STR 0,        (char **)&editor_program,
  1867.       "embedded-header-escape",    STR 0,        (char **)&saved_header_escape,
  1868. +     "enter-last-read-mode",    INT 0,        (char **)&enter_last_read_mode,
  1869.       "entry-report-limit",     INT 0,        (char **)&entry_message_limit,
  1870.       "erase-key",        KEY 0,        (char **)&erase_key,
  1871.       "expert",            BOOL 4,        (char **)&novice,
  1872. ***************
  1873. *** 1143,1149 ****
  1874.       while ((c = *options) && isascii(c) && isspace(c)) options++;
  1875.       *wp = NUL;
  1876.   
  1877. !     for (op = optab, n = 0; *op != NULL; op++, n++) {
  1878.           if (strcmp(word, *op)) continue;
  1879.           *res |= FLAG(n);
  1880.           *str = options;
  1881. --- 1194,1200 ----
  1882.       while ((c = *options) && isascii(c) && isspace(c)) options++;
  1883.       *wp = NUL;
  1884.   
  1885. !     for (op = optab, n = 1; *op != NULL; op++, n++) {
  1886.           if (strcmp(word, *op)) continue;
  1887.           *res |= FLAG(n);
  1888.           *str = options;
  1889. *** ./LAST/xmakefile    Fri Oct  5 19:07:22 1990
  1890. --- xmakefile    Fri Nov  2 20:54:15 1990
  1891. ***************
  1892. *** 150,160 ****
  1893.   * Installation
  1894.   *
  1895.   
  1896. ! cvt-help:    cvt-help.c
  1897. !     $(CC) -o cvt-help cvt-help.c
  1898.   
  1899. ! usercheck:    usercheck.c
  1900. !     $(CC) -o usercheck usercheck.c
  1901.   
  1902.   inst: config.h xmakefile inst.sh cvt-help usercheck mkprefix man/nn.1
  1903.       @echo building install script: ./inst
  1904. --- 150,160 ----
  1905.   * Installation
  1906.   *
  1907.   
  1908. ! cvt-help:    PARALLEL config.h cvt-help.c
  1909. !     $(CC) -o cvt-help cvt-help.c EXTRA_LIB
  1910.   
  1911. ! usercheck:    PARALLEL config.h usercheck.c
  1912. !     $(CC) -o usercheck usercheck.c EXTRA_LIB
  1913.   
  1914.   inst: config.h xmakefile inst.sh cvt-help usercheck mkprefix man/nn.1
  1915.       @echo building install script: ./inst
  1916. ***************
  1917. *** 179,184 ****
  1918. --- 179,185 ----
  1919.   clean:
  1920.       rm -f $(BIN_PROG) $(LIB_PROG) $(MASTER_PROG) cvt-help usercheck
  1921.       rm -f prefix mkprefix inst
  1922. +     rm -f man/nn.1 man/nn.1~
  1923.   
  1924.   *
  1925.   * dependencies
  1926.